// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Requests;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using Elastic.Transport;
using Elastic.Transport.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.Cluster;

public sealed partial class PutComponentTemplateRequestParameters : RequestParameters
{
	/// <summary>
	/// <para>
	/// If <c>true</c>, this request cannot replace or update existing component templates.
	/// </para>
	/// </summary>
	public bool? Create { get => Q<bool?>("create"); set => Q("create", value); }

	/// <summary>
	/// <para>
	/// Period to wait for a connection to the master node.
	/// If no response is received before the timeout expires, the request fails and returns an error.
	/// </para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.Duration? MasterTimeout { get => Q<Elastic.Clients.Elasticsearch.Serverless.Duration?>("master_timeout"); set => Q("master_timeout", value); }
}

/// <summary>
/// <para>
/// Create or update a component template.
/// Creates or updates a component template.
/// Component templates are building blocks for constructing index templates that specify index mappings, settings, and aliases.
/// </para>
/// <para>
/// An index template can be composed of multiple component templates.
/// To use a component template, specify it in an index template’s <c>composed_of</c> list.
/// Component templates are only applied to new data streams and indices as part of a matching index template.
/// </para>
/// <para>
/// Settings and mappings specified directly in the index template or the create index request override any settings or mappings specified in a component template.
/// </para>
/// <para>
/// Component templates are only used during index creation.
/// For data streams, this includes data stream creation and the creation of a stream’s backing indices.
/// Changes to component templates do not affect existing indices, including a stream’s backing indices.
/// </para>
/// <para>
/// You can use C-style <c>/* *\/</c> block comments in component templates.
/// You can include comments anywhere in the request body except before the opening curly bracket.
/// </para>
/// </summary>
public sealed partial class PutComponentTemplateRequest : PlainRequest<PutComponentTemplateRequestParameters>
{
	public PutComponentTemplateRequest(Elastic.Clients.Elasticsearch.Serverless.Name name) : base(r => r.Required("name", name))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.ClusterPutComponentTemplate;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "cluster.put_component_template";

	/// <summary>
	/// <para>
	/// If <c>true</c>, this request cannot replace or update existing component templates.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? Create { get => Q<bool?>("create"); set => Q("create", value); }

	/// <summary>
	/// <para>
	/// Period to wait for a connection to the master node.
	/// If no response is received before the timeout expires, the request fails and returns an error.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public Elastic.Clients.Elasticsearch.Serverless.Duration? MasterTimeout { get => Q<Elastic.Clients.Elasticsearch.Serverless.Duration?>("master_timeout"); set => Q("master_timeout", value); }

	/// <summary>
	/// <para>
	/// Marks this index template as deprecated. When creating or updating a non-deprecated index template
	/// that uses deprecated components, Elasticsearch will emit a deprecation warning.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("deprecated")]
	public bool? Deprecated { get; set; }

	/// <summary>
	/// <para>
	/// Optional user metadata about the component template.
	/// May have any contents. This map is not automatically generated by Elasticsearch.
	/// This information is stored in the cluster state, so keeping it short is preferable.
	/// To unset <c>_meta</c>, replace the template without specifying this information.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("_meta")]
	public IDictionary<string, object>? Meta { get; set; }

	/// <summary>
	/// <para>
	/// The template to be applied which includes mappings, settings, or aliases configuration.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("template")]
	public Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexState Template { get; set; }

	/// <summary>
	/// <para>
	/// Version number used to manage component templates externally.
	/// This number isn't automatically generated or incremented by Elasticsearch.
	/// To unset a version, replace the template without specifying a version.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("version")]
	public long? Version { get; set; }
}

/// <summary>
/// <para>
/// Create or update a component template.
/// Creates or updates a component template.
/// Component templates are building blocks for constructing index templates that specify index mappings, settings, and aliases.
/// </para>
/// <para>
/// An index template can be composed of multiple component templates.
/// To use a component template, specify it in an index template’s <c>composed_of</c> list.
/// Component templates are only applied to new data streams and indices as part of a matching index template.
/// </para>
/// <para>
/// Settings and mappings specified directly in the index template or the create index request override any settings or mappings specified in a component template.
/// </para>
/// <para>
/// Component templates are only used during index creation.
/// For data streams, this includes data stream creation and the creation of a stream’s backing indices.
/// Changes to component templates do not affect existing indices, including a stream’s backing indices.
/// </para>
/// <para>
/// You can use C-style <c>/* *\/</c> block comments in component templates.
/// You can include comments anywhere in the request body except before the opening curly bracket.
/// </para>
/// </summary>
public sealed partial class PutComponentTemplateRequestDescriptor<TDocument> : RequestDescriptor<PutComponentTemplateRequestDescriptor<TDocument>, PutComponentTemplateRequestParameters>
{
	internal PutComponentTemplateRequestDescriptor(Action<PutComponentTemplateRequestDescriptor<TDocument>> configure) => configure.Invoke(this);

	public PutComponentTemplateRequestDescriptor(Elastic.Clients.Elasticsearch.Serverless.Name name) : base(r => r.Required("name", name))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.ClusterPutComponentTemplate;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "cluster.put_component_template";

	public PutComponentTemplateRequestDescriptor<TDocument> Create(bool? create = true) => Qs("create", create);
	public PutComponentTemplateRequestDescriptor<TDocument> MasterTimeout(Elastic.Clients.Elasticsearch.Serverless.Duration? masterTimeout) => Qs("master_timeout", masterTimeout);

	public PutComponentTemplateRequestDescriptor<TDocument> Name(Elastic.Clients.Elasticsearch.Serverless.Name name)
	{
		RouteValues.Required("name", name);
		return Self;
	}

	private bool? DeprecatedValue { get; set; }
	private IDictionary<string, object>? MetaValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexState TemplateValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor<TDocument> TemplateDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor<TDocument>> TemplateDescriptorAction { get; set; }
	private long? VersionValue { get; set; }

	/// <summary>
	/// <para>
	/// Marks this index template as deprecated. When creating or updating a non-deprecated index template
	/// that uses deprecated components, Elasticsearch will emit a deprecation warning.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor<TDocument> Deprecated(bool? deprecated = true)
	{
		DeprecatedValue = deprecated;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Optional user metadata about the component template.
	/// May have any contents. This map is not automatically generated by Elasticsearch.
	/// This information is stored in the cluster state, so keeping it short is preferable.
	/// To unset <c>_meta</c>, replace the template without specifying this information.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor<TDocument> Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
	{
		MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The template to be applied which includes mappings, settings, or aliases configuration.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor<TDocument> Template(Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexState template)
	{
		TemplateDescriptor = null;
		TemplateDescriptorAction = null;
		TemplateValue = template;
		return Self;
	}

	public PutComponentTemplateRequestDescriptor<TDocument> Template(Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor<TDocument> descriptor)
	{
		TemplateValue = null;
		TemplateDescriptorAction = null;
		TemplateDescriptor = descriptor;
		return Self;
	}

	public PutComponentTemplateRequestDescriptor<TDocument> Template(Action<Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor<TDocument>> configure)
	{
		TemplateValue = null;
		TemplateDescriptor = null;
		TemplateDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Version number used to manage component templates externally.
	/// This number isn't automatically generated or incremented by Elasticsearch.
	/// To unset a version, replace the template without specifying a version.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor<TDocument> Version(long? version)
	{
		VersionValue = version;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (DeprecatedValue.HasValue)
		{
			writer.WritePropertyName("deprecated");
			writer.WriteBooleanValue(DeprecatedValue.Value);
		}

		if (MetaValue is not null)
		{
			writer.WritePropertyName("_meta");
			JsonSerializer.Serialize(writer, MetaValue, options);
		}

		if (TemplateDescriptor is not null)
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, TemplateDescriptor, options);
		}
		else if (TemplateDescriptorAction is not null)
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor<TDocument>(TemplateDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, TemplateValue, options);
		}

		if (VersionValue.HasValue)
		{
			writer.WritePropertyName("version");
			writer.WriteNumberValue(VersionValue.Value);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Create or update a component template.
/// Creates or updates a component template.
/// Component templates are building blocks for constructing index templates that specify index mappings, settings, and aliases.
/// </para>
/// <para>
/// An index template can be composed of multiple component templates.
/// To use a component template, specify it in an index template’s <c>composed_of</c> list.
/// Component templates are only applied to new data streams and indices as part of a matching index template.
/// </para>
/// <para>
/// Settings and mappings specified directly in the index template or the create index request override any settings or mappings specified in a component template.
/// </para>
/// <para>
/// Component templates are only used during index creation.
/// For data streams, this includes data stream creation and the creation of a stream’s backing indices.
/// Changes to component templates do not affect existing indices, including a stream’s backing indices.
/// </para>
/// <para>
/// You can use C-style <c>/* *\/</c> block comments in component templates.
/// You can include comments anywhere in the request body except before the opening curly bracket.
/// </para>
/// </summary>
public sealed partial class PutComponentTemplateRequestDescriptor : RequestDescriptor<PutComponentTemplateRequestDescriptor, PutComponentTemplateRequestParameters>
{
	internal PutComponentTemplateRequestDescriptor(Action<PutComponentTemplateRequestDescriptor> configure) => configure.Invoke(this);

	public PutComponentTemplateRequestDescriptor(Elastic.Clients.Elasticsearch.Serverless.Name name) : base(r => r.Required("name", name))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.ClusterPutComponentTemplate;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "cluster.put_component_template";

	public PutComponentTemplateRequestDescriptor Create(bool? create = true) => Qs("create", create);
	public PutComponentTemplateRequestDescriptor MasterTimeout(Elastic.Clients.Elasticsearch.Serverless.Duration? masterTimeout) => Qs("master_timeout", masterTimeout);

	public PutComponentTemplateRequestDescriptor Name(Elastic.Clients.Elasticsearch.Serverless.Name name)
	{
		RouteValues.Required("name", name);
		return Self;
	}

	private bool? DeprecatedValue { get; set; }
	private IDictionary<string, object>? MetaValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexState TemplateValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor TemplateDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor> TemplateDescriptorAction { get; set; }
	private long? VersionValue { get; set; }

	/// <summary>
	/// <para>
	/// Marks this index template as deprecated. When creating or updating a non-deprecated index template
	/// that uses deprecated components, Elasticsearch will emit a deprecation warning.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor Deprecated(bool? deprecated = true)
	{
		DeprecatedValue = deprecated;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Optional user metadata about the component template.
	/// May have any contents. This map is not automatically generated by Elasticsearch.
	/// This information is stored in the cluster state, so keeping it short is preferable.
	/// To unset <c>_meta</c>, replace the template without specifying this information.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
	{
		MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The template to be applied which includes mappings, settings, or aliases configuration.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor Template(Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexState template)
	{
		TemplateDescriptor = null;
		TemplateDescriptorAction = null;
		TemplateValue = template;
		return Self;
	}

	public PutComponentTemplateRequestDescriptor Template(Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor descriptor)
	{
		TemplateValue = null;
		TemplateDescriptorAction = null;
		TemplateDescriptor = descriptor;
		return Self;
	}

	public PutComponentTemplateRequestDescriptor Template(Action<Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor> configure)
	{
		TemplateValue = null;
		TemplateDescriptor = null;
		TemplateDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Version number used to manage component templates externally.
	/// This number isn't automatically generated or incremented by Elasticsearch.
	/// To unset a version, replace the template without specifying a version.
	/// </para>
	/// </summary>
	public PutComponentTemplateRequestDescriptor Version(long? version)
	{
		VersionValue = version;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (DeprecatedValue.HasValue)
		{
			writer.WritePropertyName("deprecated");
			writer.WriteBooleanValue(DeprecatedValue.Value);
		}

		if (MetaValue is not null)
		{
			writer.WritePropertyName("_meta");
			JsonSerializer.Serialize(writer, MetaValue, options);
		}

		if (TemplateDescriptor is not null)
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, TemplateDescriptor, options);
		}
		else if (TemplateDescriptorAction is not null)
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.IndexManagement.IndexStateDescriptor(TemplateDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("template");
			JsonSerializer.Serialize(writer, TemplateValue, options);
		}

		if (VersionValue.HasValue)
		{
			writer.WritePropertyName("version");
			writer.WriteNumberValue(VersionValue.Value);
		}

		writer.WriteEndObject();
	}
}